package com.example.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService {
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    // ===== 字符串操作 =====
    
    /**
     * 设置字符串值
     */
    public void set(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }
    
    /**
     * 设置字符串值并指定过期时间
     */
    public void set(String key, String value, long timeout, TimeUnit unit) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, unit);
    }
    
    /**
     * 获取字符串值
     */
    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }
    
    /**
     * 获取值并设置新值
     */
    public String getAndSet(String key, String newValue) {
        return stringRedisTemplate.opsForValue().getAndSet(key, newValue);
    }
    
    /**
     * 批量设置值
     */
    public void multiSet(Map<String, String> values) {
        stringRedisTemplate.opsForValue().multiSet(values);
    }
    
    /**
     * 递增操作
     */
    public Long increment(String key, long delta) {
        return stringRedisTemplate.opsForValue().increment(key, delta);
    }
    
    /**
     * 递减操作
     */
    public Long decrement(String key, long delta) {
        return stringRedisTemplate.opsForValue().decrement(key, delta);
    }
    
    // ===== 哈希操作 =====
    
    /**
     * 设置哈希值
     */
    public void hset(String key, String field, String value) {
        stringRedisTemplate.opsForHash().put(key, field, value);
    }
    
    /**
     * 批量设置哈希值
     */
    public void hmset(String key, Map<String, String> values) {
        for (Map.Entry<String, String> entry : values.entrySet()) {
            stringRedisTemplate.opsForHash().put(key, entry.getKey(), entry.getValue());
        }
    }
    
    /**
     * 获取哈希值
     */
    public String hget(String key, String field) {
        return (String) stringRedisTemplate.opsForHash().get(key, field);
    }
    
    /**
     * 获取整个哈希表
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> hgetAll(String key) {
        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(key);
        Map<String, String> result = new HashMap<>();
        entries.forEach((k, v) -> result.put(k.toString(), v.toString()));
        return result;
    }
    
    /**
     * 删除哈希表中的字段
     */
    public Long hdel(String key, String... fields) {
        return stringRedisTemplate.opsForHash().delete(key, (Object[]) fields);
    }
    
    // ===== 列表操作 =====
    
    /**
     * 从左侧添加元素
     */
    public Long lpush(String key, String... values) {
        return stringRedisTemplate.opsForList().leftPushAll(key, values);
    }
    
    /**
     * 从右侧添加元素
     */
    public Long rpush(String key, String... values) {
        return stringRedisTemplate.opsForList().rightPushAll(key, values);
    }
    
    /**
     * 获取列表范围
     */
    public List<String> lrange(String key, long start, long end) {
        return stringRedisTemplate.opsForList().range(key, start, end);
    }
    
    /**
     * 获取列表长度
     */
    public Long llen(String key) {
        return stringRedisTemplate.opsForList().size(key);
    }
    
    /**
     * 从左侧弹出元素
     */
    public String lpop(String key) {
        return stringRedisTemplate.opsForList().leftPop(key);
    }
    
    /**
     * 从右侧弹出元素
     */
    public String rpop(String key) {
        return stringRedisTemplate.opsForList().rightPop(key);
    }
    
    // ===== 集合操作 =====
    
    /**
     * 添加元素到集合
     */
    public Long sadd(String key, String... values) {
        return stringRedisTemplate.opsForSet().add(key, values);
    }
    
    /**
     * 获取集合所有元素
     */
    public Set<String> smembers(String key) {
        return stringRedisTemplate.opsForSet().members(key);
    }
    
    /**
     * 检查元素是否在集合中
     */
    public Boolean sismember(String key, String value) {
        return stringRedisTemplate.opsForSet().isMember(key, value);
    }
    
    /**
     * 获取集合大小
     */
    public Long scard(String key) {
        return stringRedisTemplate.opsForSet().size(key);
    }
    
    /**
     * 移除元素
     */
    public Long srem(String key, String... values) {
        return stringRedisTemplate.opsForSet().remove(key, (Object[]) values);
    }
    
    // ===== 有序集合操作 =====
    
    /**
     * 添加元素到有序集合
     */
    public Boolean zadd(String key, String value, double score) {
        return stringRedisTemplate.opsForZSet().add(key, value, score);
    }
    
    /**
     * 获取有序集合范围（按分数从小到大）
     */
    public Set<String> zrange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().range(key, start, end);
    }
    
    /**
     * 获取有序集合范围（按分数从大到小）
     */
    public Set<String> zrevrange(String key, long start, long end) {
        return stringRedisTemplate.opsForZSet().reverseRange(key, start, end);
    }
    
    /**
     * 获取元素分数
     */
    public Double zscore(String key, String value) {
        return stringRedisTemplate.opsForZSet().score(key, value);
    }
    
    /**
     * 获取有序集合大小
     */
    public Long zcard(String key) {
        return stringRedisTemplate.opsForZSet().zCard(key);
    }
    
    // ===== 通用操作 =====
    
    /**
     * 检查键是否存在
     */
    public Boolean exists(String key) {
        return stringRedisTemplate.hasKey(key);
    }
    
    /**
     * 删除键
     */
    public Boolean delete(String key) {
        return stringRedisTemplate.delete(key);
    }
    
    /**
     * 批量删除键
     */
    public Long delete(Set<String> keys) {
        return stringRedisTemplate.delete(keys);
    }
    
    /**
     * 设置过期时间
     */
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return stringRedisTemplate.expire(key, timeout, unit);
    }
    
    /**
     * 获取键的过期时间
     */
    public Long getExpire(String key, TimeUnit unit) {
        return stringRedisTemplate.getExpire(key, unit);
    }
    
    /**
     * 重命名键
     */
    public void rename(String oldKey, String newKey) {
        stringRedisTemplate.rename(oldKey, newKey);
    }
    
    // ===== 事务操作 =====
    
    /**
     * 执行事务操作
     */
    public void executeTransaction(RedisCallback<Object> action) {
        stringRedisTemplate.execute(action);
    }
    
    /**
     * 执行Redis命令
     */
    public <T> T execute(RedisCallback<T> action) {
        return stringRedisTemplate.execute(action);
    }
}
